package com.bsj.sipgateway.sip.transmit.request.impl;

import com.bsj.sipgateway.cache.DeviceCache;
import com.bsj.sipgateway.common.constant.Constants;
import com.bsj.power.common.def.entity.gb28181.Device;
import com.bsj.sipgateway.sip.bean.Position;
import com.bsj.sipgateway.sip.event.EventPublisher;
import com.bsj.sipgateway.sip.transmit.request.SIPRequestAbstractProcessor;
import com.bsj.sipgateway.util.NumericUtil;
import com.bsj.sipgateway.util.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.SipException;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.ByteArrayInputStream;
import java.text.ParseException;

/**
 * @Description: Notify请求处理器
 * @author bsj-chenjunkang
 * @date 2022/8/31
 */
@Slf4j
public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {


    private EventPublisher publisher;


    private static final String NOTIFY_CATALOG = "Catalog";
    private static final String NOTIFY_ALARM = "Alarm";
    private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";

    @Override
    public void process(RequestEvent evt) {
        try {
            Element rootElement = getRootElement(evt);
            String cmd = XmlUtil.getText(rootElement, "CmdType");

            if (NOTIFY_CATALOG.equals(cmd)) {
                log.info("接收到Catalog通知");
                processNotifyCatalogList(evt);
            } else if (NOTIFY_ALARM.equals(cmd)) {
                log.info("接收到Alarm通知");
                processNotifyAlarm(evt);
            } else if (NOTIFY_MOBILE_POSITION.equals(cmd)) {
                log.info("接收到MobilePosition通知");
                processNotifyMobilePosition(evt);
            } else {
                log.info("接收到消息：" + cmd);
                response200Ok(evt);
            }
        } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理MobilePosition移动位置Notify
     *
     * @param evt
     */
    private void processNotifyMobilePosition(RequestEvent evt) {
        try {
            // 回复 200 OK
            Element rootElement = getRootElement(evt);
            Element deviceIdElement = rootElement.element("DeviceID");
            String deviceId = deviceIdElement.getTextTrim();
            Device device = DeviceCache.getDevice(deviceId);
            if (device == null) {
                log.error("Notify接收MobilePosition数据时设备不在线，deviceId:{}", deviceId);
                return;
            }
            Position position = new Position();
            String longitude = XmlUtil.getText(rootElement, "Longitude");
            String latitude = XmlUtil.getText(rootElement, "Latitude");
            String speed = XmlUtil.getText(rootElement, "Speed");
            String direction = XmlUtil.getText(rootElement, "Direction");
            if (NumericUtil.isDouble(longitude)) {
                position.setLongitude(Double.parseDouble(longitude));
            }
            if (NumericUtil.isDouble(latitude)) {
                position.setLatitude(Double.parseDouble(latitude));
            }
            if (NumericUtil.isFloat(speed)) {
                position.setSpeed(Float.parseFloat(speed));
            }
            if (NumericUtil.isShort(direction)) {
                position.setDirect(Short.parseShort(direction));
            }
            response200Ok(evt);
            publisher.onlineEventPublish(device, Constants.EVENT_ONLINE_KEEPLIVE, position);
        } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
            e.printStackTrace();
        }
    }

    /***
     * 处理alarm设备报警Notify
     *
     * @param evt
     */
    private void processNotifyAlarm(RequestEvent evt) {
        try {
            Element rootElement = getRootElement(evt);
            Element deviceIdElement = rootElement.element("DeviceID");
            String deviceId = deviceIdElement.getText().toString();


        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /***
     * 处理catalog设备目录列表Notify
     *
     * @param evt
     */
    private void processNotifyCatalogList(RequestEvent evt) {
        try {

            response200Ok(evt);

        } catch (SipException | InvalidArgumentException | ParseException e) {
            e.printStackTrace();
        }
    }

    /***
     * 回复200 OK
     *
     * @param evt
     * @throws SipException
     * @throws InvalidArgumentException
     * @throws ParseException
     */
    private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
        Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
        //设置设备的外网端口
        setRport(evt, response);
        getServerTransaction(evt).sendResponse(response);
    }

    private Element getRootElement(RequestEvent evt) throws DocumentException {
        Request request = evt.getRequest();
        SAXReader reader = new SAXReader();
        reader.setEncoding("gbk");
        Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
        return xml.getRootElement();
    }

    public void setPublisher(EventPublisher publisher) {
        this.publisher = publisher;
    }
}
